/**
 * 文件名：SecurityInterceptor.java
 *
 * 创建人：虞云波 - .com
 *
 * 创建时间：2017年10月9日 下午3:57:05
 *
 * 版权所有：江苏晟邦网络科技有限公司
 */
package com.cbwl.eoas.web.framework.action;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.cbwl.eoas.common.cache.redis.RedisCache;
import com.cbwl.eoas.common.file.ExceptionPropertiesUtil;
import com.cbwl.eoas.common.framework.utils.JSONUtil;
import com.cbwl.eoas.common.util.DateUtil;
import com.cbwl.eoas.common.util.DigestUtil;
import com.cbwl.eoas.common.web.Result;
import com.cbwl.eoas.web.framework.annotation.InterceptorUrl;

/**
 * <p>[描述信息：签名校验拦截器]</p>
 *o
 * @author 虞云波 - yuyunbo@3856.cc
 * @version 1.0 Created on 2017年10月9日 下午3:57:05
 */
public class SecurityInterceptor extends HandlerInterceptorAdapter{

	
	private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
	
	@Autowired
	private RedisCache<String,String> redisCache;
	
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		
		if(handler instanceof HandlerMethod){
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			Method method = handlerMethod.getMethod();
			InterceptorUrl annotation = method.getAnnotation(InterceptorUrl.class);
			if(annotation == null){
				return true;
			}
			int diffSecond = annotation.validsecond();
			int validnum = annotation.validnum();
			log.info("有效性"+diffSecond);
			Result result = new Result(Result.Status.OK, "请求成功", "200");
			response.setContentType("text/html;charset=UTF-8");
			String path = request.getServletPath();
			log.info("请求的路径"+path);
			// 是否为ajax请求
			String requestType = request.getHeader("X-Requested-With");
			
			String timeStamp = request.getParameter("timeStamp");
			String tokenId = request.getParameter("tokenId");
			String signature = request.getParameter("signature");
			
			//获取所有参数生成签名
			Enumeration<?> pNames =  request.getParameterNames();  
			Map<String, String> params = new HashMap<String, String>(); 
			while (pNames.hasMoreElements()) {  
			  String pName = (String) pNames.nextElement();  
			  String pValue = request.getParameter(pName);  
			  params.put(pName, pValue);  
			}
			params.remove("signature");
			String checksign = DigestUtil.digest(params);
			
			String validNum = redisCache.getStr(checksign);
			if(StringUtils.isEmpty(validNum)){
				redisCache.putStr(checksign, "1",30);
			}else{
				redisCache.putStr(checksign, String.valueOf(Integer.valueOf(validNum)+1),30);
			}
			
			if(!StringUtils.isEmpty(signature)){
				//存在签名,判断签名是否正确
				//两次签名不正确
				if(!signature.equals(checksign)){
					result.setCode("CBWL-000004");
					response.getWriter().print(JSONUtil.getJSONString(result));
					response.getWriter().close();
					return false;
				}
			}else{
				//签名必传
				result.setCode("CBWL-000010");
				response.getWriter().print(JSONUtil.getJSONString(result));
				response.getWriter().close();
				return false;
			}
			
			//时间戳和tokenId必传
			if(StringUtils.isEmpty(timeStamp)){
				if ("XMLHttpRequest".equals(requestType)) {
					response.setStatus(801);
				} else {
					result.setCode("CBWL-000010");
					response.getWriter().print(JSONUtil.getJSONString(result));
					response.getWriter().close();
				}
				return false;
			}else{
				
				if(!StringUtils.isEmpty(timeStamp)){
					//相差秒，url的失效性
					if(diffSecond>0 && DateUtil.dateDiffMilliSecond(new Date(Long.valueOf(timeStamp)), new Date())>diffSecond*1000){
						result.setCode("CBWL-000009");
						response.getWriter().print(JSONUtil.getJSONString(result));
						response.getWriter().close();
						return false;
					}
					if(validnum>0){
						if(Integer.valueOf(redisCache.getStr(checksign)) >validnum){
							result.setCode("CBWL-000011");
							response.getWriter().print(JSONUtil.getJSONString(result));
							response.getWriter().close();
							return false;
						}
					}
				}else{
					result.setCode("CBWL-000010");
					response.getWriter().print(JSONUtil.getJSONString(result));
					response.getWriter().close();
					return false;
				}
				
				if(!StringUtils.isEmpty(tokenId) && StringUtils.isEmpty(redisCache.getStr(tokenId))){
						//tokenId过期
						result.setCode("CBWL-000008");
						response.getWriter().print(JSONUtil.getJSONString(result));
						response.getWriter().close();
						return false;
				}
			}
		return true;
	}else{
		return super.preHandle(request, response, handler);
	}

	}
	
	
	public static void main(String[] args) {
		System.out.println(ExceptionPropertiesUtil.getExceptionDesc("CBWL-000004"));
		System.out.println(String.valueOf(null));
	}
	
}
